class Blue{
    constructor(options={}){// 默认值
        const _this = this;
        this.timer = null;
        this._root = document.querySelector(options.root);
        this._methods = options.methods;
        
        let proxy = new Proxy(options.data(),{
            set(data,name,val){
                data[name] = val;
                _this.render();
                return true;
            }
        });

        this._parent = this._root.parentNode;// 备份原版parent
        // this._template = document.createDocumentFragment();
        // this._template.appendChild(this._root);
        this._template = this._root.cloneNode(true);// 克隆原版root

        _this.update();
        this._proxy = proxy;// 方便调用
        return proxy;// 实例化对象需要使用
    }
    update(){
        clearTimeout(this.timer);
        this.timer = setTimeout(() => {
            this.render();
        }, 0);
    }
    render(){
        console.log('render');
        let root = this._template.cloneNode(true);

        Array.from(root.childNodes).forEach(child=>{
            if(child.nodeType == document.TEXT_NODE){
                child.data = child.data.replace(/\{\{[^\}]+\}\}/g,(str)=>{// 查找并替换数据
                    str = str.substring(2,str.length-2);
                    let arr = [];
                    for (const key in this._proxy) { // 也可以用 Object.keys(this._proxy).forEach((key)=>{}
                        arr.push(`let ${key} = ${JSON.stringify(this._proxy[key])};`);// 通过 JSON.stringify 给字符串加引号
                    }
                    arr.push(str);// 把表达式也加入
                    
                    return eval(arr.join(''));// 返回数据 强大地 eval 可以运算字符串内的表达式
                });
            }
        })
        
        Array.from(root.children).forEach(child=>{
            Array.from(child.attributes).forEach(attr=>{
                if(attr.name.startsWith('@')){
                    let attrName = attr.name.substr(1);
                    
                    /* 
                    child.addEventListener(attrName, ()=>{
                        let arr = [];
                        for (const key in this._methods) {
                            arr.push(`let ${key} = this._methods.${key};`);
                        }
                        arr.push(attr.value+`.call(this._proxy)`);
                        eval(arr.join(''));
                    }, false);
                     */


                     
                    let arr = [];
                    arr.push(`child.addEventListener('${attrName}', this._methods.${attr.value}.bind(this._proxy), false);`);
                    eval(arr.join('')); 
                    
                    
                }
            })
        })
        

        this._parent.replaceChild(root,this._root);
        this._root = root;

        // console.log(this._template);
        
    }
}